package com.we.wfc.common.base;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import com.we.wfc.common.enums.ReturnCode;
import com.we.wfc.common.utils.CommonUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.repository.JpaRepository;

import java.io.Serializable;
import java.time.OffsetDateTime;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * BaseService 基础实现
 *
 * @param <T>
 * @param <ID>
 * @param <R>
 */
public abstract class BaseServiceImpl<T extends BaseJpaEntity, ID extends Serializable, R extends JpaRepository<T, ID>> implements BaseService<T, ID, R> {

    @Autowired
    protected R baseMapper;

    /**
     * 查询单条记录
     *
     * @param id
     * @return
     */
    @Override
    public T findById(ID id) {
        return baseMapper.findById(id).orElse(null);
    }

    @Override
    public boolean existsById(ID var1) {
        return baseMapper.existsById(var1);
    }

    @Override
    public List<T> findAll() {
        return baseMapper.findAll();
    }

    @Override
    public List<T> findAll(Sort sort) {
        return baseMapper.findAll(sort);
    }

    @Override
    public Optional<T> findOne(Example<T> var1) {
        return baseMapper.findOne(var1);
    }

    @Override
    public List<T> findAll(Example<T> var1) {
        return baseMapper.findAll(var1);
    }

    @Override
    public List<T> findAll(Example<T> var1, Sort var2) {
        return baseMapper.findAll(var1, var2);
    }

    @Override
    public Page<T> findAll(Example<T> var1, Pageable var2) {
        return baseMapper.findAll(var1, var2);
    }

    @Override
    public Page<T> findAll(Pageable var1) {
        return baseMapper.findAll(var1);
    }

    @Override
    public long count(Example<T> var1) {
        return baseMapper.count(var1);
    }

    @Override
    public boolean exists(Example<T> var1) {
        return baseMapper.exists(var1);
    }

    @Override
    public long count() {
        return baseMapper.count();
    }

    /**
     * 保存entity
     *
     * @param t
     * @return
     */
    @Override
    public T save(T t) {
        // 判断是否为更新
        if (ObjectUtil.isNull(t.getId())) {
            // 插入 初始化基础数据
            t.setId(IdUtil.simpleUUID())
                    .setCreateBy(CommonUtil.getCurrentId())
                    .setCreateDate(OffsetDateTime.now())
                    .setUpdateBy(CommonUtil.getCurrentId())
                    .setUpdateDate(OffsetDateTime.now());
            return baseMapper.save(t);
        } else {
            // 更新
            T dbT = baseMapper.findById((ID) t.getId())
                    .orElseThrow(() -> new BaseException(ReturnCode.NOT_FOUND_DATA));
            // 忽略为空的Copy
            BeanUtil.copyProperties(t, dbT, CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));
            dbT.setUpdateBy(CommonUtil.getCurrentId())
                    .setUpdateDate(OffsetDateTime.now());
            return baseMapper.save(dbT);
        }
    }

    /**
     * 批量保存
     *
     * @param var1
     * @return
     */
    @Override
    public List<T> saveAll(List<T> var1) {
        /** 初始化 */
        List<T> collect = var1.stream().map(t -> {
            // 判断是否为更新
            if (ObjectUtil.isNull(t.getId())) {
                // 插入 初始化基础数据
                t.setId(IdUtil.simpleUUID())
                        .setCreateBy(CommonUtil.getCurrentId())
                        .setCreateDate(OffsetDateTime.now())
                        .setUpdateBy(CommonUtil.getCurrentId())
                        .setUpdateDate(OffsetDateTime.now());
                return t;
            } else {
                // 更新
                T dbT = baseMapper.findById((ID) t.getId()).orElse(null);
                if (ObjectUtil.isNotNull(dbT)) {
                    // 忽略为空的Copy
                    BeanUtil.copyProperties(t, dbT, CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));
                    dbT.setUpdateBy(CommonUtil.getCurrentId())
                            .setUpdateDate(OffsetDateTime.now());
                }
                return dbT;
            }
        }).collect(Collectors.toList());
        return baseMapper.saveAll(collect);
    }

    @Override
    public void deleteById(ID id) {
        baseMapper.deleteById(id);
    }

    @Override
    public void deleteInBatch(List<T> entities) {
        baseMapper.deleteInBatch(entities);
    }

    @Override
    public void deleteById4Logic(ID id) {
        // 逻辑删除
        baseMapper.findById(id).ifPresent(entity -> {
            entity.setDelFlag(new Byte("1"));
            save(entity);
        });
    }

    @Override
    public void deleteById4LogicInBatch(List<ID> entities) {
        entities.forEach(id -> deleteById4Logic(id));
    }
}
